home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / THINKC / 4_0 / GNUUCP_2 / SOURCE / SYSDEP.AMI < prev    next >
Text File  |  1989-07-31  |  14KB  |  556 lines

  1. /*
  2.  * @(#)sysdep.amiga 1.2 87/09/23    Copyright 1987 Free Software Foundation, Inc.
  3.  *
  4.  * Copying and use of this program are controlled by the terms of the
  5.  * GNU Emacs General Public License.
  6.  */
  7.  
  8. #ifndef lint
  9. char sysdep_version[] = "@(#)sysdep.amiga gnuucp Version hoptoad-1.2";
  10. #endif
  11.  
  12. /*
  13.  * Created 23 Sept 1987 by John Gilmore, using material from sysdep.unix
  14.  * and from an older Amiga uuslave port by:
  15.  * William Loftus  (burdvax!wpl), Feb 1987
  16.  */
  17.  
  18. #include "includes.h"
  19. #include "uucp.h"
  20. #include "sysdep.h"
  21.  
  22. #define    MULTITASK
  23. #define    STDIN        0
  24. #define    LIBDIR        "/usr/lib/uucp"
  25. #define    CONTROL        "/usr/lib/uucp/gnuucp.ctl"
  26. #define    PUBDIR        "/usr/spool/uucppublic"
  27. #define    LOGFILE        "LOGFILE"
  28. #define    O_BINARY    0    /* No distinction between text and binary */
  29.  
  30. /*
  31.  * Exported variables
  32.  */
  33. char     sysdep_control[] = CONTROL;
  34.  
  35.  
  36. /* Our variables */
  37.  
  38. /* Declarations for the serial read and write. */
  39. extern struct MsgPort *CreatePort();
  40. struct IOExtSer *Read_Request;
  41. static char rs_in[2];
  42. struct IOExtSer *Write_Request;
  43. static char rs_out[2];
  44. struct timerequest Timer;
  45. struct MsgPort *Timer_Port = NULL;
  46.  
  47. void sigint();                /* Forward declaration */
  48.  
  49. /*
  50.  * Open the serial line for an incoming call.
  51.  * Argument of NULL or empty string means stdin.
  52.  */
  53. int
  54. openline(ttynam, baud)
  55.     char    *ttynam;
  56.     int    baud;
  57. {
  58.     int ontheline = !(ttynam && ttynam[0]);    /* FIXME, this is garbage */
  59.     int c;
  60.  
  61.     Read_Request =
  62.        (struct IOExtSer *)AllocMem(sizeof(*Read_Request),
  63.                        MEMF_PUBLIC|MEMF_CLEAR);
  64.  
  65.     Read_Request->io_SerFlags = SERF_SHARED | SERF_XDISABLED;
  66.     Read_Request->IOSer.io_Message.mn_ReplyPort =
  67.                        CreatePort("Read_RS",0);
  68.  
  69.     if(OpenDevice(SERIALNAME,NULL,Read_Request,NULL)) {
  70.       printf("Can not open serial port for read.\n");
  71.       DeletePort(Read_Request->IOSer.io_Message.mn_ReplyPort);
  72.       FreeMem(Read_Request,sizeof(*Read_Request));
  73.       exit(TRUE);
  74.     }
  75.  
  76.     Read_Request->IOSer.io_Length = 1;
  77.     Read_Request->IOSer.io_Data = (APTR) &rs_in[0];
  78.  
  79.     Write_Request =
  80.        (struct IOExtSer *)AllocMem(sizeof(*Write_Request),
  81.                        MEMF_PUBLIC|MEMF_CLEAR);
  82.  
  83.     Write_Request->io_SerFlags = SERF_SHARED | SERF_XDISABLED;
  84.  
  85.     Write_Request->IOSer.io_Message.mn_ReplyPort =
  86.                     CreatePort("Write_RS",0);
  87.  
  88.     if(OpenDevice(SERIALNAME,NULL,Write_Request,NULL)) {
  89.        printf("Can not open open serial port for write.\n");
  90.        DeletePort(Write_Request->IOSer.io_Message.mn_ReplyPort);
  91.        FreeMem(Write_Request,sizeof(*Write_Request));
  92.        DeletePort(Read_Request->IOSer.io_Message.mn_ReplyPort);
  93.        FreeMem(Read_Request,sizeof(*Read_Request));
  94.        exit(TRUE);
  95.      }
  96.  
  97.     Write_Request->IOSer.io_Command = CMD_WRITE;
  98.     Write_Request->IOSer.io_Length = 1;
  99.     Write_Request->IOSer.io_Data = (APTR) &rs_out[0];
  100.  
  101.     Read_Request->io_SerFlags = 0L;
  102.     Read_Request->io_Baud = baud;
  103.     Read_Request->io_ReadLen = 8L;
  104.     Read_Request->io_WriteLen = 8L;
  105.     Read_Request->io_CtlChar = 0x11130000L;
  106.     Read_Request->io_BrkTime = 750000;
  107.     Read_Request->IOSer.io_Command = SDCMD_SETPARAMS;
  108.  
  109.     DoIO(Read_Request);
  110.  
  111.     Read_Request->IOSer.io_Command = CMD_READ;
  112.  
  113.     Timer_Port = CreatePort("Timer Port",0L);
  114.  
  115.     if (OpenDevice(TIMERNAME, UNIT_VBLANK, (char *) &Timer, 0))  {
  116.        printf("Can't open timer device.");
  117.        DeletePort(Write_Request->IOSer.io_Message.mn_ReplyPort);
  118.        FreeMem(Write_Request,sizeof(*Write_Request));
  119.        DeletePort(Read_Request->IOSer.io_Message.mn_ReplyPort);
  120.        FreeMem(Read_Request,sizeof(*Read_Request));
  121.        exit(TRUE);
  122.     }
  123.  
  124.     Timer.tr_node.io_Message.mn_ReplyPort = Timer_Port;
  125.     Timer.tr_node.io_Command = TR_ADDREQUEST;
  126.     Timer.tr_node.io_Flags = 0;
  127.     Timer.tr_node.io_Error = 0;
  128.  
  129.     BeginIO(Read_Request);
  130.     xwrite(msgo6,sizeof(msgo6)-1); /* set up terminal */
  131.  
  132.     signal(SIGINT,sigint);
  133.  
  134. begin_again:
  135.         printf("Start again!!\n");
  136.  
  137.         c = xgetc();
  138.         while (c == EOF) { c = xgetc(); printf(".");}  /* wait for input */
  139.  
  140.         printf("\nHey what was that?\n");
  141.         printf("Got %c\n %d %d %c",c,c,c & 0xFF,c & 0xFF);
  142.  
  143.     /* now we have something !! */
  144.     /* Not nice, but fast! */
  145.  
  146.     if ((c) == 'C') {
  147.       c = xgetc();
  148.       printf("C got %c\n",c);
  149.       if ((c) == 'O') {
  150.         c = xgetc();
  151.         printf("CO got %c\n",c);
  152.         if ((c) == 'N') {
  153.           c = xgetc();
  154.           if ((c) == 'N') {
  155.         c = xgetc();
  156.         if ((c) == 'E') {
  157.           c = xgetc();
  158.           if ((c) == 'C') {
  159.             c = xgetc();
  160.             if ((c) == 'T') {
  161.               c = xgetc();
  162.               if ((c) == ' ') {
  163.             c = xgetc();
  164.             if ((c) == '1') {
  165.               c = xgetc();
  166.               if ((c) == '2') {
  167.                 c = xgetc();
  168.                 if ((c) == '0') {
  169.                   c = xgetc();
  170.                   if ((c) == '0') {
  171.                 c = xgetc();
  172.                 if ((c) == '\r') {
  173.                   DEBUG(1,"Someone is rapping, rapping at my ...\n", 0);
  174.                   /* do it !!! */
  175.                   c = xgetc();
  176.                   while (c  != EOF) c = xgetc(); /* zap trash*/
  177.                   return;
  178.                 } else goto begin_again;
  179.                   } else goto begin_again;
  180.                 } else goto begin_again;
  181.               } else goto begin_again;
  182.             } else goto begin_again;
  183.               } else goto begin_again;
  184.             } else goto begin_again;
  185.           } else goto begin_again;
  186.         } else goto begin_again;
  187.           } else goto begin_again;
  188.         } else goto begin_again;
  189.       } else goto begin_again;
  190.     } else goto begin_again;
  191. }
  192.  
  193. /*
  194.  * Open the serial line for an outgoing call.
  195.  */
  196. int
  197. openout(ttynam, baud)
  198.     char    *ttynam;
  199.     int    baud;
  200. {
  201.  
  202.     abort();        / FIXME -- write for amiga */
  203.  
  204.     signal(SIGINT,sigint);
  205.     return SUCCESS;
  206. }
  207.  
  208. /*
  209.  * Basement level I/O routines
  210.  *
  211.  * xwrite() writes a character string to the serial port
  212.  * xgetc() returns a character from the serial port, or an EOF for timeout.
  213.  * sigint() restores the state of the serial port on exit.
  214.  * hangup() hangs up the serial port (e.g. drop DTR).
  215.  */
  216.  
  217. int
  218. xgetc()
  219. {
  220.     int rd,ch;
  221.  
  222.     /* printf("\nxgetc\n"); */
  223.  
  224.     Timer.tr_time.tv_secs = BYTE_TIMEOUT;
  225.     Timer.tr_time.tv_micro = 0;
  226.     SendIO((char *) &Timer.tr_node);
  227.     /* BeginIO((char *) &Timer.tr_node);*/
  228.  
  229.     rd = FALSE;
  230.     while (rd == FALSE)
  231.         {
  232.         Wait((1L << Read_Request->IOSer.io_Message.mn_ReplyPort->mp_SigBit) |
  233.             ( 1L << Timer_Port->mp_SigBit));
  234.         if (CheckIO(Read_Request)) {
  235.             WaitIO(Read_Request);
  236.             ch=rs_in[0];
  237.             rd = TRUE;
  238.             SendIO(Read_Request);
  239.             }
  240.         if (rd == FALSE && CheckIO((char*) &Timer)) {
  241.             WaitIO((char*)&Timer);
  242.             /*printf("TIMEOUT\n");*/
  243.             return(EOF);  /* Time out!!! */
  244.             }
  245.         }     /* end while */
  246.  
  247.     /* printf("Before AbortIO & Wait \n"); */
  248.  
  249.     if (!CheckIO((char *) &Timer))
  250.        AbortIO((char *) &Timer);
  251.     else
  252.        WaitIO((char *) &Timer);
  253.  
  254.     /* Wait (1L << Timer_Port->mp_SigBit); */
  255.     /* printf(" Returning '%c'\n",ch & 0xFF); */
  256.  
  257.     return(ch);
  258. }
  259.  
  260. int
  261. xwrite(buf,ctr)
  262.     char *buf;
  263.     int ctr;
  264. {
  265.     int i;
  266.  
  267.     for (i=0; i < ctr; i++) {
  268.         rs_out[0] = (*buf++) & 0xFF;
  269.         DoIO(Write_Request);
  270.     }
  271.     return 1;
  272. }
  273.  
  274. sigint()
  275. {
  276.     CloseDevice(Write_Request);
  277.     DeletePort(Write_Request->IOSer.io_Message.mn_ReplyPort);
  278.     FreeMem(Write_Request,sizeof(*Write_Request));
  279.     CloseDevice(Read_Request);
  280.     DeletePort(Read_Request->IOSer.io_Message.mn_ReplyPort);
  281.     FreeMem(Read_Request,sizeof(*Read_Request));
  282.     DeletePort(Timer_Port);
  283.     printf("User requested termination.\n");
  284.     exit(TRUE);
  285. }
  286.  
  287. /*
  288.  * hangup(): hang up the 'fone.
  289.  */
  290. int
  291. hangup()
  292. {
  293.  
  294.     abort();    /* FIXME -- write for Amiga */
  295.     sleep(2);        /* To be sure DTR stays down that long */
  296. }
  297.  
  298.  
  299. /*
  300.  * Create a temporary file name for receiving a file into.
  301.  * "name" is the name we will actually eventually want to use for the file.
  302.  * We currently ignore it, but some OS's that can't move files around
  303.  * easily might want to e.g. put the temp file into the same directory
  304.  * that this file is going into.
  305.  *
  306.  * FIXME:
  307.  * This interface should be able to return a "possible" filename, and
  308.  * be re-called if the name is already in use, to get another.
  309.  * This avoids checking here whether the name is good -- saving system calls.
  310.  */
  311. char *
  312. temp_filename(name)
  313.     register char *name;
  314. {
  315.     static char tname[NAMESIZE];
  316.  
  317.     if (ourpid == 0)
  318.         ourpid = getpid();
  319.     (void) sprintf(tname, "TM.u%d", ourpid);
  320.     DEBUG(7, "Using temp file %s\n", tname);
  321.     return tname;
  322. }
  323.  
  324.  
  325. /*
  326.  * Transform a filename from a uucp packet (in Unix format) into a local
  327.  * filename that will work in the local file system.
  328.  */
  329. char *
  330. munge_filename(name)
  331.     register char *name;
  332. {
  333.     register char *p;
  334.     static char buffer[NAMESIZE+SLOP];
  335.     int len, hostlen;
  336.  
  337.     DEBUG(7, "Munge_filename  input: %s\n", name);
  338.  
  339.     /* FIXME: Security checking goes here! */
  340.  
  341.     if (name[0] == '~') {
  342.         /* Handle user-relative names -- ~ or ~uucp turns to PUBDIR */
  343.         if (name[1] == '/')
  344.             p = &name[1];
  345.         else if (!strncmp("~uucp/", name, 6))
  346.             p = &name[5];
  347.         else {
  348.             p = NULL;        /* Neither of the above */
  349.             goto out;
  350.         }
  351.         strcpy(buffer, PUBDIR);
  352.         strcat(buffer, p);
  353.         p = buffer;
  354.         goto out;
  355.     }
  356.  
  357. #ifdef SUBDIR
  358.     /* Berkeley Unix subdirectory hack.
  359.      * Full pathnames go through OK.
  360.      * D.myname*    -> D.myname/D.myname*
  361.      * D.*        -> D./D.*
  362.      * C.*        -> C./C.*
  363.      * otherwise left alone (e.g. X.*, LCK.*, STST.*).
  364.      * FIXME: I hear Honey Danber has a slightly different scheme.
  365.      * In particular, STST's go in a directory.
  366.      */
  367.     if (name[0] != '/') {
  368.         if (name[1] == '.' &&
  369.             (name[0] == 'C' || name[0] == 'D')) {
  370.             len = strlen(name);
  371.             hostlen = strlen(Myname);
  372.             if (hostlen > 7) hostlen = 7;
  373.             /* Check D.mynameAxxxx case */
  374.             if (name[0] == 'D' && len == hostlen + 2 + 5 &&
  375.                 !strncmp(&name[2], Myname, hostlen))
  376.                 len = 2 + hostlen;    /* "D."+name */
  377.             else
  378.                 len = 2;        /* Just "D." */
  379.             strcpy(buffer, name);
  380.             buffer[len] = '/';
  381.             strcpy(buffer+len+1, name);
  382.             p = buffer;
  383.             goto out;
  384.         }
  385.     }
  386. #endif
  387.  
  388.     p = name;        /* Let it through as-is. */
  389.  
  390. out:
  391.     DEBUG(7, "Munge_filename output: %s\n", p);
  392.     return p;
  393. }
  394.  
  395. /*
  396.  * Uucp work queue scan.
  397.  *
  398.  * gotsome = work_scan(hostname, type);
  399.  * workfile = work_next();
  400.  * void work_done();
  401.  */
  402.  
  403. /*
  404.  * Local variables of the work queue scanner -- not visible to outsiders
  405.  *
  406.  * Workhost and worktype are always null-terminated; keeping their lengths
  407.  * is just a performance hack.  Workprefix is NOT null terminated; various
  408.  * people copy things after it and use the whole string.  Workprefix is
  409.  * exactly workplen long; to append something, strcpy(workprefix+workplen, ...)
  410.  */
  411. #define MAX_TYPE    10
  412. static DIR    *workdir = (DIR *)NULL;
  413. static struct dirent    *workfile;
  414. static char    workhost[MAX_HOST+1];
  415. static int    workhlen;
  416. static char    worktype[MAX_TYPE+1];
  417. static int    worktlen;
  418. static char    workfirst = 0;
  419. /* FIXME, at the moment this can be local to work_scan() */
  420. static char    workprefix[MAX_TYPE+1+MAX_HOST+1+MAX_TYPE+1+MAX_HOST+6+SLOP];
  421.         /*       D        . hoptoad  / D        . hoptoad  N1234\0 */
  422. static int    workplen;
  423.  
  424. void
  425. work_done()
  426. {
  427.     if (workdir)
  428.         closedir(workdir);
  429.     workdir = (DIR *) NULL;
  430.     workfile = (struct dirent *) NULL;
  431.     workfirst = 0;
  432. }
  433.  
  434.  
  435. int
  436. work_scan(host, type)
  437.     char *host;
  438.     char *type;
  439. {
  440.     char *p;
  441.  
  442.     if (!host)
  443.         host = "";
  444.  
  445.     /* If called twice in a row, don't thrash the disk again */
  446.     if (strcmp(workhost, host) == SAME &&
  447.         strcmp(worktype, type) == SAME && workfile)
  448.         return 1;
  449.  
  450.     if (workdir) work_done();        /* Clean up prev call */
  451.  
  452.     workfirst = 1;                /* Initialize for work_next */
  453.     workhlen = strlen(host);
  454.     if (workhlen > sizeof (workhost) -1) abort();
  455.     strcpy(workhost, host);
  456.     if (workhlen > 7) workhlen = 7;        /* Unix uucp limit */
  457.     worktlen = strlen(type);
  458.     if (worktlen > sizeof (worktype) -1) abort();
  459.     strcpy(worktype, type);
  460.  
  461.     /* Figure out which subdirectory this class of files is in. */
  462.     /* FIXME: doesn't handle "all D. files" since D.myname is separate. */
  463.     sprintf(workprefix, "%s.%s", worktype, workhost);
  464.     p = munge_filename(workprefix);
  465.     strcpy(workprefix, p);
  466.     p = index(workprefix, '/');
  467.     if (p)
  468.         workplen = 1 + p - workprefix;    /* Prefix ends after '/' */
  469.     else
  470.         workplen = 0;        /* No / in munged; hence no dir */
  471.     workprefix[workplen] = '\0';
  472.     DEBUG(7, "Work prefix is =%s=\n", workprefix);
  473.  
  474.     strcpy(workprefix+workplen, ".");
  475.     workdir = opendir(workprefix);    /* Open whatever directory */
  476.     if (workdir == NULL) {
  477.         DEBUG(0, "Can't open queue directory %s\n", workprefix);
  478.         return 0;            /* No work */
  479.     }
  480.  
  481.     return work_look();
  482. }
  483.  
  484.  
  485. static int
  486. work_look()
  487. {
  488.     int len;
  489.  
  490.     for (;;) {
  491.         workfile = readdir(workdir);
  492.         if (workfile == NULL) {
  493.             DEBUG(7, "work_look readdir null\n", 0);
  494.             work_done();
  495.             return 0;        /* No work */
  496.         }
  497.         DEBUG(7, "work_look readdir %s\n", workfile->d_name);
  498.  
  499.         /* Is it the right type? */
  500.         if (strncmp(workfile->d_name, worktype, worktlen) == SAME
  501.             && workfile->d_name[worktlen] == '.') {
  502.             /* see if it matches the hostname */
  503.             len = strlen(workfile->d_name);
  504.             /*         "C"        "." "hoptoad" "Xnnnn" */
  505.             if (workhlen == 0 || 
  506.                 (len == worktlen + 1 + workhlen + 5 && 
  507.                  !strncmp(workhost, workfile->d_name+2, workhlen))
  508.                ) {
  509.                 /* Found an entry! */
  510.                 /* FIXME, check grade letter! */
  511.                 DEBUG(7, "work_look found it!\n", 0);
  512.                 return 1;    /* Found work */
  513.             }
  514.         }
  515.     }
  516.     /* NOTREACHED */
  517. }
  518.  
  519.  
  520. char *
  521. work_next()
  522. {
  523.  
  524.     if (!workfirst) {
  525.         if (!workfile || !work_look())
  526.             return (char *)NULL;
  527.     }
  528.     workfirst = 0;
  529.  
  530.     return workfile->d_name;
  531. }
  532.  
  533. /*
  534.  * Routine to return a string that gives the current date and time, and
  535.  * identifies the current process, if on a multiprocess system.
  536.  */
  537. char *
  538. time_and_pid()
  539. {
  540.     long clock;
  541.     struct tm *tm;
  542.     static int ourpid = 0;
  543.     static char format[] = "%d/%d-%d:%02d:%02d-%d";
  544.     static char outbuf[sizeof(format)];
  545.  
  546.     (void) time(&clock);
  547.     tm = localtime(&clock);
  548.     if (ourpid == 0)
  549.         ourpid = getpid();
  550.     sprintf(outbuf, format,
  551.         tm->tm_mon+1, tm->tm_mday,
  552.         tm->tm_hour, tm->tm_min, tm->tm_sec,
  553.         ourpid);
  554.     return outbuf;
  555. }
  556.